# == Coding: UTF-8 ==
# @Project :        ExcelKeywordDriverTest
# @fileName         keys_words
# @version          v0.1
# @author           16980
# @GiteeWarehouse   https://gitee.com/liu-long068/
# @editsession      2023/3/8
# @Software:        PyCharm
# ====/******/=====
import time

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.keys import Keys

from public.common.log import Log

success = "SUCCESS   "
fail = "FAIL   "
logger = Log()


def open_browser(type_):
    options = webdriver.ChromeOptions()
    options.add_argument('ignore-certificate-errors')
    if type_ == 'Chrome' or 'chrome':
        driver = getattr(webdriver, type_)(chrome_options=options)
    else:
        try:
            driver = getattr(webdriver, type_)(chrome_options=options)
        except Exception:
            driver = webdriver.Chrome(chrome_options=options)
    return driver


class Keys_words:
    def __init__(self, txt):
        self.driver = open_browser(txt)

    def log_info(self, msg):
        logger.info(msg)

    def log_error(self, msg):
        logger.error(msg)

    def element_wait(self, name, value, secs=5):
        # if name or value is None:
        #     raise NameError("定位语法错误或为空！")
        messages = "元素{0}在{1}时间内没有找到！".format(value, secs)
        if name == 'id':
            WebDriverWait(self.driver, secs, 1).until(EC.presence_of_element_located((By.ID, value)), messages)
        elif name == 'name':
            WebDriverWait(self.driver, secs, 1).until(EC.presence_of_element_located((By.NAME, value)), messages)
        elif name == 'class':
            WebDriverWait(self.driver, secs, 1).until(EC.presence_of_element_located((By.CLASS_NAME, value)), messages)
        elif name == 'link_text':
            WebDriverWait(self.driver, secs, 1).until(EC.presence_of_element_located((By.LINK_TEXT, value)), messages)
        elif name == 'xpath':
            WebDriverWait(self.driver, secs, 1).until(EC.presence_of_element_located((By.XPATH, value)), messages)
        elif name == 'css':
            WebDriverWait(self.driver, secs, 1).until(EC.presence_of_element_located((By.CSS_SELECTOR, value)),
                                                      messages)
        else:
            raise NameError("请确认你的定位元素是否是'id','name','class','link_text','xpath','css'。")

    def open(self, txt):
        t1 = time.time()
        try:
            self.driver.get(txt)
            self.log_info("{0} Navigated to {1}, Spend {2} seconds".format(success, txt, time.time() - t1))
        except Exception:
            self.log_error("{0} Unable to load {1}, Spend {2} seconds".format(success, txt, time.time() - t1))
            raise

    def get_element(self, name, value):
        # return self.driver.find_element(name, value)
        if name == 'id':
            element = self.driver.find_element(By.ID, value)
        elif name == 'name':
            element = self.driver.find_element(By.NAME, value)
        elif name == 'class':
            element = self.driver.find_element(By.CLASS_NAME, value)
        elif name == 'link_text':
            element = self.driver.find_element(By.LINK_TEXT, value)
        elif name == 'xpath':
            element = self.driver.find_element(By.XPATH, value)
        elif name == 'css':
            element = self.driver.find_element(By.CSS_SELECTOR, value)
        else:
            raise NameError("请输入正确的目标元素，'id'，'name'，'class'，'link_text'，'xpaht'，'css'")
        return element

    def max_window(self):
        """ Set browser window maximized."""
        t1 = time.time()
        self.driver.maximize_window()
        self.log_info("{0} Set browser window maximized, Spend {1} seconds".format(success, time.time() - t1))

    def set_window(self, wide, high):
        t1 = time.time()
        self.driver.set_window_size(wide, high)
        self.log_info("{0} Set browser window wide: {1},high: {2}, Spend {3} seconds".format(success, wide, high,
                                                                                             time.time() - t1))

    def click(self, name, value):
        t1 = time.time()
        try:
            self.element_wait(name, value)
            self.get_element(name, value).click()
            self.log_info("{0} Clicked element: <{1}>, Spend {2} seconds".format(success, value, time.time() - t1))
        except Exception:
            self.log_error(
                "{0} Unable to click element: <{1}>, Spend {2} seconds".format(fail, value, time.time() - t1))
            raise

    def send_keys(self, name, value, txt):
        t1 = time.time()
        try:
            self.element_wait(name, value)
            el = self.get_element(name, value)
            el.clear()
            el.send_keys(txt)
            self.log_info(
                "{0} Clear and type element: <{1}> content: {2}, Spend {3} seconds".format(success, value, txt,
                                                                                           time.time() - t1))
        except Exception:
            self.log_error("{0} Unable to clear and type element: <{1}> content: {2}, Spend {3} seconds".format(fail,
                                                                                                                value,
                                                                                                                txt,
                                                                                                                time.time() - t1))
            raise

    def clear_type(self, name, value, txt):
        """
        Clear and input element.
        """
        t1 = time.time()
        try:
            self.element_wait(name, value)
            el = self.get_element(name, value)
            el.send_keys(Keys.CONTROL, 'a')
            el.send_keys(Keys.DELETE)
            el.send_keys(txt)
            self.log_info("{0} Clear and type element: <{1}> content: {2}, Spend {3} seconds".format(success,
                                                                                                     value, txt,
                                                                                                     time.time() - t1))
        except Exception:
            self.log_error("{0} Unable to clear and type element: <{1}> content: {2}, Spend {3} seconds".format(fail,
                                                                                                                value,
                                                                                                                txt,
                                                                                                                time.time() - t1))
            raise

    def right_click(self, name, value):
        t1 = time.time()
        try:
            self.element_wait(name, value)
            el = self.get_element(name, value)
            ActionChains(self.driver).context_click(el).perform()
            self.log_info("{0} Right click element: <{1}>, Spend {2} seconds".format(success, value, time.time() - t1))
        except Exception:
            self.log_error(
                "{0} Unable to right click element: <{1}>, Spend {2} seconds".format(fail, value, time.time() - t1))
            raise

    def move_to_element(self, name, value):
        t1 = time.time()
        try:
            self.element_wait(name, value)
            el = self.get_element(name, value)
            ActionChains(self.driver).move_to_element(el).perform()
            self.log_info("{0} Move to element: <{1}>, Spend {2} seconds".format(success, value, time.time() - t1))
        except Exception:
            self.log_error("{0} unable move to element: <{1}>, Spend {2} seconds".format(fail, value, time.time() - t1))
            raise

    def quit(self):
        t1 = time.time()
        self.driver.quit()
        self.log_info("{0} Closed all window and quit the driver, Spend {1} seconds".format(success, time.time() - t1))

    def sleep(self, txt):
        time.sleep(int(txt))

    def get_text(self, name, value):
        t1 = time.time()
        try:
            self.element_wait(name, value)
            text = self.get_element(name, value).text
            return text
        except Exception:
            raise

    def assert_text(self, name, value, expect):
        try:
            reality = self.get_element(name, value).text
            assert expect == reality, "断言失败，实际结果为：{}".format(reality)
            return True
        except Exception as e:
            # +str(e) 将e 为字符串
            print("断言失败，信息错误：{}" + str(e))
            return False

    def switch_to_window(self):
        t1 = time.time()
        try:
            win_list = self.driver.window_handles
            self.driver.switch_to.window(win_list[-1])
            self.log_info("{0} Click element: open a new window and swich into, Spend {1} seconds".format(success,
                                                                                                          time.time() - t1))
        except Exception:
            self.log_error("{0} Click element: open a new window and swich into, Spend {1} seconds".format(fail,
                                                                                                           time.time() - t1))
            raise

    def accept_alert(self):
        """
        Accept warning box.

        Usage:
        driver.accept_alert()
        """
        t1 = time.time()
        self.driver.switch_to.alert.accept()
        self.log_info("{0} Accept warning box, Spend {1} seconds".format(success, time.time() - t1))

    def select_visible_text(self, name, value, txt):
        """ 根据下拉值选择 """
        t1 = time.time()
        try:
            self.element_wait(name, value)
            ele = self.get_element(name, value)
            s = Select(ele)
            s.select_by_visible_text(txt)
            self.log_info("{0}Select by visible text, Spend {1} seconds".format(success, time.time() - t1))
        except Exception:
            self.log_error("{0}Select by visible text, Spend {1} seconds".format(fail, time.time() - t1))
            raise
